import { Middleware, IMiddleware } from '@midwayjs/core';
import { NextFunction, Context } from '@midwayjs/koa';

// let routes = require('../../view/router.json');
import * as fs from 'fs';
import * as _path from 'path';

@Middleware()
export class WebMiddleware implements IMiddleware<Context, NextFunction> {
  resolve() {
    return async (ctx: Context, next: NextFunction) => {
      // 控制器前执行的逻辑
      // console.log('全局路由守卫', ctx);
      let path = ctx.path;
      // 需将改中间件放置在最前，才能处理模板被下载的问题

      // 安全过滤，全部返回404
      // 过滤ejs nunjucks模板文件
      if (path.endsWith('.ejs') || path.endsWith('.nj')) {
        return ctx.status = 404;
      }
      // 过滤掉路由配置文件
      if (path === '/view/route.json') {
        return ctx.status = 404;
      }
      // 取项目根目录下的view/router.json文件

      const jsonData = await fs.readFileSync(_path.join(__dirname, '../../view/router.json'), 'utf-8');
      const routes = JSON.parse(jsonData);
      const roots = Object.keys(routes).map(key => routes[key].root);
      // 判断是否包含根目录
      if (roots.some(root => path.startsWith(root))) {
        // 是否请求根目录
        const isRoot = path.endsWith('/');
        if (isRoot) {
          path = path + 'index';
        } else {
          // 去掉请求扩展名后缀
          const index = path.lastIndexOf('.');
          if (index > 0) path = path.substring(0, index);
        }
        // /view/sample/demo/index
        // console.log('fixPath: ', path);
        const routerKeys = Object.keys(routes);
        for (let i = 0; i < routerKeys.length; i++) {
          const key = routerKeys[i];
          const route = routes[key];
          const parentPath = route.root + route.path.replace('.ejs', '');
          // 目录匹配检查
          if (path === parentPath) {
            // url完全匹配检查
            return ctx.forward('/web/');
          }
          // 子录匹配检查
          if (route.child) {
            for (let j = 0; j < route.child.length; j++) {
              const child = route.child[j];
              const childPath = route.root + child.path.replace('.ejs', '');
              if (path === childPath) {
                return ctx.forward('/web/');
              }
            }
          }
        }
      }

      // 执行下一个 Web 中间件，拿到下一个中间件或者控制器的返回值
      const result = await next();
      // 控制器之后执行的逻辑
      // 返回给上一个中间件的结果
      return result;
    };
  }

  match(ctx: Context): boolean {
    // 仅处理/view开头的路由
    if (ctx.path.startsWith('/view/')) {
      return true;
    }
  }

  static getName(): string {
    return 'web';
  }
}
